import { Injectable } from '@angular/core';
import { Observable,throwError } from 'rxjs';

import { HttpParams, HttpClient, HttpHeaders } from '@angular/common/http';
import { map, catchError } from 'rxjs/operators';
import * as _ from 'lodash';
import { Md5 } from 'ts-md5';
import { TreeNode } from 'primeng/api';
import { AppSettings, UserRoles, UserStatus } from '../config/app-settings';

@Injectable({
  providedIn: 'root'
})
export class UserService {
  currentUser: any;


  public static defaultProfile = {
    "personalID": "",
    "username": "",
    "password": "",
    "firstName": "",
    "middleName": "",
    "lastName": "",
    "role": "",
    "status": "",
    "code": "",
    "referID": "",
    "email": "",
    "sex": "",
    "age": 0,
    "mobile": "",
    "country": "",
    "state": "",
    "city": "",
    "street": "",
    "position": "",
    "company": "",
    "experience": 0,
    "createTime": "",
    "updateTime": ""
  }
  constructor(private httpClient: HttpClient) { }





  loadUserList(role?): Observable<any> {
    let header = _.cloneDeep(AppSettings.httpServerHeader);
    if (role) {
      header.params = new HttpParams().set('role', role);
    }
    return this.httpClient.get<any>(`${AppSettings.server_base}/user`, header).pipe(map((res) => res['data']));
  }

  getUserById(id): Observable<any> {
    let header = _.cloneDeep(AppSettings.httpServerHeader);
    return this.httpClient.get<Array<any>>(`${AppSettings.server_base}/user/${id}`, header).pipe(map(res => res['success'] ? res['data'] : []));
  }

  getUserList(filter): Observable<any> {
    let header = _.cloneDeep(AppSettings.httpServerHeader);
    if (filter) {
      header.params = filter;
    }
    return this.httpClient.get<Array<any>>(`${AppSettings.server_base}/user`, header).pipe(map(res => res['success'] ? res['data'] : []));
  }

  getExternalUser(code): Observable<any> {
    let header = _.cloneDeep(AppSettings.httpServerHeader);
    header.params = new HttpParams().set('code', code);
    return this.httpClient.get<Array<any>>(`${AppSettings.server_base}/user/external`, header).pipe(map(res => res['success'] ? res['data'] : []));
  }

  /**mock */
  getSubagentKPI(referID) {
    let header = _.cloneDeep(AppSettings.httpServerHeader);
    return this.httpClient.get<Array<any>>(`${AppSettings.mock_base}/shared/subagentkpi.json`, {
      withCredentials: true,
      params: new HttpParams().set('mock', 'true'),
      headers: new HttpHeaders().set('Content-Type', 'application/json')
    }).pipe(map(res => <TreeNode[]>res['data']));


  }

  //add user, approve directly and set emal
  addUser(user): Observable<any> {
    let header = _.cloneDeep(AppSettings.httpServerHeader);
    return this.httpClient.post<any>(`${AppSettings.server_base}/user`, user, header);
  }

  //add user, approve directly and set emal
  getMainContent(): Observable<any> {
    let header = _.cloneDeep(AppSettings.httpServerHeader);
    return this.httpClient.get<any>(`${AppSettings.server_base}/content?module=index_video_configuration`, header)
      .pipe(
        map(res => res.data),
        catchError((err) => { return throwError("no login session, redirect to login page") })
      );
  }

  // register user
  registerUser(user): Observable<any> {
    let header = _.cloneDeep(AppSettings.httpServerHeader);
    return this.httpClient.post<any>(`${AppSettings.server_base}/user/register`, user, header);
  }

  //login
  loginUser(code, password): Observable<any> {
    let header = _.cloneDeep(AppSettings.httpServerHeader);
    return this.httpClient.post<any>(`${AppSettings.server_base}/user/login`, { code: code, password: password }, header);
  }

  //logout
  logout(): Observable<any> {
    let header = _.cloneDeep(AppSettings.httpServerHeader);
    return this.httpClient.get<any>(`${AppSettings.server_base}/user/logout`, header);
  }

  //get current login user
  getCurrentUser(): Observable<any> {
    let header = _.cloneDeep(AppSettings.httpServerHeader);
    return this.httpClient.get<any>(`${AppSettings.server_base}/user/current-user`, header)
      .pipe(
        map(res => res.data),
        catchError((err) => { return throwError("no login session, redirect to login page") })
      );
  }

  updateUser(user): Observable<any> {
    let header = _.cloneDeep(AppSettings.httpServerHeader);
    return this.httpClient.put<any>(`${AppSettings.server_base}/user`, user, header);
  }

  //submit registeration after I agree T&C
  applySubmit(id): Observable<any> {
    let header = _.cloneDeep(AppSettings.httpServerHeader);
    return this.httpClient.put<any>(`${AppSettings.server_base}/user/apply/${id}`, {}, header);
  }

  patch(id, patch): Observable<any> {
    let header = _.cloneDeep(AppSettings.httpServerHeader);
    return this.httpClient.patch<any>(`${AppSettings.server_base}/user/${id}`, patch, header);

  }

  createBuyer(patch): Observable<any> {
    let header = _.cloneDeep(AppSettings.httpServerHeader);
    return this.httpClient.post<any>(`${AppSettings.server_base}/user/buyer`, patch, header)
      .pipe(
        map(res => res.data),
      );
  }

  approveUser(user, type): Observable<any> {
    let header = _.cloneDeep(AppSettings.httpServerHeader);
    header.params = new HttpParams().set('type', type);
    return this.httpClient.put<any>(`${AppSettings.server_base}/user/approve/${user.id}`, user, header);
  }

  deleteUser(id): Observable<any> {
    let header = _.cloneDeep(AppSettings.httpServerHeader);
    header.params = new HttpParams().set('id', id);
    return this.httpClient.delete<any>(`${AppSettings.server_base}/user`, header)
  }


  getFullName(user) {
    return user ? `[${user.code}]:${user.firstName || ''},${user.lastName || ''}` : '';
  }

  isActive(user) {
    return user.code && user.status === UserStatus.ACTIVE;
  }

  MD5(val) {
    return Md5.hashAsciiStr(val);
  }

  getHash() {
    return Math.random().toString(36).slice(2);
  }


}
